#include "Image.h"

#define STB_IMAGE_IMPLEMENTATION
#define STBI_ONLY_PNG
#include "stb_image.h"

void Image::LoadFromFile(const std::string &path)
{
  stbi_set_flip_vertically_on_load(true);
  unsigned char *imgData = stbi_load(path.c_str(), &width, &height, &channels, 0);
  if (!imgData)
  {
    LOG_ERROR("Failed to load texture: {}", path);
    return;
  }
  data.resize(width * height * channels);
  memcpy(data.data(), imgData, width * height * channels);
  stbi_image_free(imgData);
}

Image Image::SubImage(glm::uvec2 offset, glm::uvec2 extent) const
{
  assert((offset.x + extent.x) <= width && (offset.y + extent.y) <= height);

  Image NewImage{extent.x, extent.y};
  const uint32_t RowPitch = width * sizeof(uint32_t);
  for (uint32_t y = 0; y < extent.y; ++y) {
    const size_t SrcOffset = ((offset.y + y) * RowPitch) + (offset.x * sizeof(uint32_t));

    const auto SourceRow = std::span<const std::uint8_t>(data.data() + SrcOffset, extent.x * sizeof(uint32_t));

    NewImage.data.insert(NewImage.data.begin(), SourceRow.begin(), SourceRow.end());
  }

  return NewImage;
}